Repository navigation
feat(rest): support query auth for REST catalog tables - #534
Open
SteNicholas wants to merge 1 commit into
Open
SteNicholas wants to merge 1 commit into
SteNicholas wants to merge 1 commit into
Conversation
SteNicholas
force-pushed
the
PAIMON-520
branch
3 times, most recently
from
November 6, 2026 20:06
ec531b4 to
b0fb5cd
Compare
Enforce the row filters and column masks a REST catalog defines for
tables with `query-auth.enabled=true`.
- RestCatalog: implement `QueryAuthCatalog::AuthTableQuery` against
`POST .../tables/{table}/auth`, with new `AuthTableQueryRequest` and
`AuthTableQueryResponse` messages. External tables get no rules.
- TableQueryAuthResult: parse the predicate and transform JSON into a
row filter and NULL, FIELD_REF, CONCAT, CONCAT_WS and SUBSTRING
masks, refuse malformed or unsupported rules, and validate them
against a schema by column name, type and field id.
- QueryAuthTableScan: fetch and validate the rules on every plan, push
down only the row filter and the predicate conjuncts on unmasked
columns, and wrap each split in a `QueryAuthSplit`.
- QueryAuthTableRead: apply the row filter, then the masks, then the
read predicate, and refuse a split whose authorized columns no
longer match the schema read.
- Split: serialize `QueryAuthSplit` with the field ids its rules were
authorized for.
- TableScan/TableRead: enable query auth from the catalog's branch
schema, and refuse paths that would bypass the rules: search,
explicit read schemas, real-time and fallback reads, global index
scans and the $files, $binlog, $audit_log and $ro system tables.
- ScanContextBuilder: add `SetReadFieldNames`; the scan and read
context builders carry the `branch` option into the catalog
identifier.
- Like: let `_` match any character, including a line terminator.
SteNicholas
force-pushed
the
PAIMON-520
branch
from
November 7, 2026 06:43
b0fb5cd to
58c299b
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose
Linked issue: close #520
A REST catalog can restrict what a query on a table with
query-auth.enabled=truereturns, through row filters and column masks. This PR fetches those rules from the catalog at plan time, carries them on each split, and applies them when the split is read. Read paths that would bypass the rules are refused.Catalog
RestCatalogimplementsQueryAuthCatalog::AuthTableQueryonPOST /v1/{prefix}/databases/{database}/tables/{table}/auth, using the newAuthTableQueryRequestandAuthTableQueryResponsemessages. External tables get no rules.TableQueryAuthResultparses the rule JSON into a row filter andNULL,FIELD_REF,CONCAT,CONCAT_WSandSUBSTRINGmasks. It refuses malformed or unsupported rules and validates them against a schema by column name, type and field id.Scan and read
QueryAuthTableScanfetches and validates the rules on every plan, pushes down only the row filter and the predicate conjuncts on unmasked columns, and wraps each split in aQueryAuthSplit.QueryAuthTableReadapplies the row filter, then the masks, then the read predicate. It refuses a split whose authorized columns no longer match the schema being read.QueryAuthSplitserializes with the field ids its rules were authorized for.TableScan::CreateandTableRead::Createturn query auth on from the catalog's schema for the branch read, and refuse search, explicit read schemas, real-time and fallback reads, global index scans, and the$files,$binlog,$audit_logand$rosystem tables.Other
ScanContextBuilder::SetReadFieldNames(). The scan and read context builders now carry thebranchoption into the catalog identifier.LIKE,_now matches any character, including a line terminator.Tests
TableQueryAuthResultTest.*covers rule parsing, literal types and boundaries, constant folding, masks, schema and field-id validation, and malformed or unsupported rules.QueryAuthSplitTest.*covers deserializing the fixtures undertest/test_data/query_auth/, round trips, and malformed bytes.QueryAuthTableReadTest.*covers dictionary and large-string decoding, and closing readers when a split fails.TableTest.TestQueryAuth*plans and reads through a mock query-auth catalog, covering branches, schema changes, pruning and limit pushdown, primary-key, deletion-vector and data-evolution tables, and refused read paths.RestCatalogTest.*QueryAuth*,RestCatalogTest.AuthTableQuery*,RestApiTest.AuthTableQuery,RestMessagesTest.AuthTableQuery*andResourcePathsTest.*cover the endpoint, the messages, retries and error mapping.ScanContextTest.TestWithCatalogResolvesTheBranch,ReadContextTest.TestWithCatalogResolvesTheBranch,SchemaValidationTest.TestQueryAuth,FormatTableTest.TestQueryAuthInTheSchemaCannotBeDisabledAtTheCall,PredicateTest.TestLikeWildcardsMatchLineTerminators,RapidJsonUtilTest.TestRejectUnescapedNul,RapidJsonUtilTest.TestSerializeStringWithEmbeddedNul,RapidJsonUtilTest.TestCheckNoDuplicateMembers,DataTypeJsonParserTest.ParseTypeRejectsEmbeddedNul,CoreOptionsTest.TestDefaultValueandCoreOptionsTest.TestFromMap.BlobTableInteTestcases that read a missing upstream table now expectNotExist.API and Format
Options::QUERY_AUTH_ENABLED(query-auth.enabled),ScanContextBuilder::SetReadFieldNames(),ScanContext::GetReadFieldNames()and aScanContextconstructor that takes the read field names. Updates theWithCatalog()docs of both context builders.QueryAuthSplittogether with its authorized field ids. Other splits, and the table's data and metadata files, are unchanged.POST .../tables/{table}/auth.Documentation
docs/source/user_guide/catalog.rstdocuments the option, the supported rules, how a query-auth table is planned and read, the refused read paths, and the limits of query-auth splits across runtimes.Generative AI tooling
Generated-by: Claude Code (2.1.311, Claude Opus 5.5)
🤖 Generated with Claude Code